package com.zjh.admin.controller;

import com.zjh.admin.entity.DAO.SysUserEntity;
import com.zjh.admin.entity.VO.OnlineSysUserVO;
import com.zjh.admin.entity.VO.ResetPasswordVO;
import com.zjh.admin.entity.VO.SysUserVO;
import com.zjh.admin.service.UserService;
import com.zjh.admin.websocket.handle.GlobalWebSocketHandler;
import com.zjh.common.SSE.entity.SSEDataBody;
import com.zjh.common.SSE.service.Impl.SSEServiceImpl;
import com.zjh.common.SSE.service.SSEService;
import com.zjh.common.config.SecurityConfig;
import com.zjh.common.entity.LoginUser;
import com.zjh.common.entity.Response;
import com.zjh.common.exception.ServiceException;
import com.zjh.common.utils.RequestContext;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.mvc.method.annotation.SseEmitter;
import org.springframework.web.socket.TextMessage;
import org.springframework.web.socket.WebSocketSession;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Set;

@RestController
@RequestMapping("/Admin/sysUser")
public class sysUserController {

    @Autowired
    private UserService userService;

    @Autowired
    private SecurityConfig securityConfig;

    @Resource
    private SSEService sseService;

    @GetMapping("/all")
    @ApiOperation(value = "查询所有用户信息")
    public Response<List<SysUserEntity>> getAllUsr() {
        List<SysUserEntity> users = userService.getAllUsers();
        return Response.success(users);
    }

    @ApiOperation(value = "添加用户", notes = "添加一个用户,传入用户名和地址")
    @PostMapping("/add")
    public Response insertUsr(@RequestBody SysUserVO usr) {
        System.out.println(usr);
        Assert.isTrue(!Objects.isNull(usr.getUsername()), "用户名不能为空");
        Assert.isTrue(!Objects.isNull(usr.getRoleId()), "用户角色不能为空");
        Assert.isTrue(!Objects.isNull(usr.getPassword()), "用户密码不能为空");

        usr.setPassword(securityConfig.bCryptPasswordEncoder().encode(usr.getPassword()));

        try {
            userService.addUser(usr);
            return Response.success("添加用户成功");
        } catch (Exception e) {
            return Response.error("添加用户失败: " + e.getMessage());
        }

    }

    @ApiOperation(value = "删除用户", notes = "根据用户Id删除用户")
    @PostMapping("/deleteUserByUserId")
    public Response deleteUserByUserId(@RequestParam Integer userId) {
        LoginUser loginUser = RequestContext.getLoginUser();
        if (Objects.isNull(loginUser)) {
            throw new ServiceException("当前登陆用户信息为空");
        }

        if (loginUser.getRoleId() != 1) {
            throw new ServiceException("非管理员用户无法删除其他用户");
        }
        userService.deleteUserById(userId);
        return Response.success("删除用户成功");

    }

    @ApiOperation(value = "编辑用户", notes = "根据用户Id编辑用户")
    @PostMapping("/editUserByUserId")
    public Response editUserByUserId(@RequestBody SysUserEntity usr) {
        LoginUser loginUser = RequestContext.getLoginUser();
        if (Objects.isNull(loginUser)) {
            throw new ServiceException("当前登陆用户信息为空");
        }

        if (loginUser.getRoleId() != 1) {
            throw new ServiceException("非管理员用户无法编辑其他用户");
        }
        userService.updateUser(usr);
        return Response.success("编辑用户成功");

    }

    /**
     * 重置密码前的校验
     */
    @PostMapping("resetPasswordValid")
    public Response<?> resetPasswordValid(@RequestBody ResetPasswordVO resetPasswordVO) {
        Boolean aBoolean = userService.resetPasswordValid(resetPasswordVO);
        if (aBoolean) {
            return Response.success();
        } else {
            return Response.error("初始密码错误");
        }
    }

    @PostMapping("resetPassword")
    public Response<?> resetPassword(@RequestBody ResetPasswordVO resetPasswordVO) {
        userService.resetPassword(resetPasswordVO);

        return Response.success("重置密码成功", null);
    }

    @GetMapping("/queryone")
    @ApiOperation(value = "根据用户名查找用户", notes = "根据用户名查找用户")
    public Response<SysUserEntity> queryByUsername(@RequestParam("username") String username) {
        SysUserEntity usr = userService.getUserByUsername(username);
        return Response.success(usr);
    }

    @GetMapping("/queryoneByUserId")
    @ApiOperation(value = "根据用户Id查找用户", notes = "根据用户名查找用户")
    public Response<SysUserEntity> queryoneByUserId(@RequestParam("userId") String userId) {
        Long _userId = Long.valueOf(userId);
        SysUserEntity usr = userService.getUserById(_userId);
        return Response.success(usr);
    }


    @GetMapping("/getOnlineUser")
    public Response<List<OnlineSysUserVO>> getOnlineUser() {
        List<OnlineSysUserVO> res = new ArrayList<>();

        GlobalWebSocketHandler.socketMap_userName_session.values().stream()
                .flatMap(Set::stream) // 将多个 Set<WebSocketSession> 合并成一个 Stream<WebSocketSession>
                .forEach(session -> {
                    // 获取其他信息，如：
                    String userName = session.getPrincipal().getName();

                    SysUserEntity userByUsername = userService.getUserByUsername(userName);
                    if (!Objects.isNull(userByUsername)) {
                        res.add(OnlineSysUserVO.builder()
                                .username(userName)
                                .nickname(userByUsername.getNickname())
                                .sessionId(session.getId())
                                .build());
                    }


                });


        return Response.success(res);
    }

    @GetMapping("/getOnlineUserBySSE")
    public Response<List<OnlineSysUserVO>> getOnlineUserBySSE() {

        List<OnlineSysUserVO> res = new ArrayList<>();

        SSEServiceImpl.emitters.forEach((clientId, emitter) -> {
            SSEDataBody sseDataBody = sseService.paraSSEData(clientId);

            if ("SystemClock".equals(sseDataBody.getPageType())) {
                OnlineSysUserVO item = new OnlineSysUserVO();
                BeanUtils.copyProperties(sseDataBody, item);

                SysUserEntity userByUsername = userService.getUserByUsername(sseDataBody.getUsername());
                if (!Objects.isNull(userByUsername)) {
                    item.setNickname(userByUsername.getNickname());
                    res.add(item);
                }

            }
        });

        return Response.success(res);
    }

    @PostMapping("/forceOfflineUser")
    public Response<Void> forceOfflineUser(@RequestParam("sessionId") String sessionId) {

        WebSocketSession webSocketSession = GlobalWebSocketHandler.sessionMap_id_session.get(sessionId);
        try {
            webSocketSession.sendMessage(new TextMessage("disconnect"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return Response.success();
    }

    @PostMapping("/forceOfflineUserBySSE")
    public Response<Void> forceOfflineUserBySSE(@RequestParam("username") String username, @RequestParam("ip") String ip) {

        SSEServiceImpl.emitters.forEach((clientId, emitter) -> {

            SSEDataBody sseDataBody = sseService.paraSSEData(clientId);

            if ("SystemClock".equals(sseDataBody.getPageType())) {
                if (username.equals(sseDataBody.getUsername()) && ip.equals(sseDataBody.getIp())) {

                    sseDataBody.setData("logout");
                    try {
                        emitter.send(SseEmitter.event().data(sseDataBody));
                    } catch (IOException e) {
                        // 发送失败，移除该客户端
                        SSEServiceImpl.emitters.remove(clientId);
                    }
                }
            }
        });

        return Response.success();
    }

}
